package com.atbeijing.gmall.realtime.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.text.StrBuilder;
import org.apache.flink.api.java.tuple.Tuple2;
import redis.clients.jedis.Jedis;

import java.util.List;

/**
 * 从hbase查询维度表的工具类
 */
public class DimUtil {

    /**
     * 直接从Phoenix中查询维度数据，没有使用缓存优化
     * @param tableName 表名
     * @param columnNameAndValues 过滤条件Tuple2<列名,值>.
     * @return
     */
    public static JSONObject getDimInfoNoCache(String tableName, Tuple2<String,String>... columnNameAndValues){
        //拼接查询sql
        StrBuilder querySql = new StrBuilder("select * from " + tableName + " where ");
        for (int i = 0; i < columnNameAndValues.length; i++) {
            if (i>0){
                querySql.append(" and ")  ;
            }
            querySql.append(columnNameAndValues[i].f0 +"='"+columnNameAndValues[i].f1+"'");
        }
        System.out.println("查询维度的sql为：" + querySql);

        //通过phoenix工具类查询数据
        List<JSONObject> dimJsonObjectList = PhoenixUtil.queryList(querySql.toString(), JSONObject.class);
        JSONObject dimJsonObj = null;
        if (dimJsonObjectList!=null && dimJsonObjectList.size()>0){
            //维度表都是通过id查的这里确定只有一条
            dimJsonObj=dimJsonObjectList.get(0);
        }else {
            System.out.println("没有查询到维度数据:" + querySql);
        }
        return dimJsonObj;
    }

    /**
     * Phoenix中查询维度数据，使用旁路缓存优化
     *         先从缓存中查询维度数据，如果缓存中有，直接将维度数据返回；如果缓存中没有维度数据，再到Phoenix中
     *         查询维度数据，然后将查询出来的维度数据放到缓存中，下次直接从缓存中获取。
     *     缓存选型：Redis
     *         dim:dim_user_info:10_zs
     *         key拼接:  dim:表名:值_值    redis的value的type为:  String        expire:1day
     * @param tableName 表名
     * @param columnNameAndValues 过滤条件Tuple2<列名,值>.
     * @return
     */
    public static JSONObject getDimInfo(String tableName, Tuple2<String, String>... columnNameAndValues) {
        //拼接操作redis的key
        StringBuilder redisKey = new StringBuilder("dim:" + tableName.toLowerCase() + ":");
        //拼接查询维度表的sql
        StringBuilder querySql = new StringBuilder("select * from " + tableName + " where ");
        
        for (int i = 0; i < columnNameAndValues.length; i++) {
            String columnName = columnNameAndValues[i].f0;
            String value = columnNameAndValues[i].f1;
            if (i>0){
                redisKey.append("_");
                querySql.append(" and ");
            }
            redisKey.append(value);
            querySql.append(columnName + " = '" + value + "'");
        }

        //jedis连接
        Jedis jedis=null;
        //存放从redis查出来的数据
        String dimJsonStr=null;
        //存放最终返回结果
        JSONObject dimJsonObj = null;

        //从redis中查询维度表数据,有可能失败,失败了还可以去hbase查询,所以要处理异常,让程序继续执行
        try {
            jedis = RedisUtil.getJedis();
            dimJsonStr = jedis.get(redisKey.toString());
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("查询缓存异常");
        }

        //redis查到数据直接返回,没查到去hbase查询
        if (dimJsonStr!=null && dimJsonStr.length()>0){
            System.out.println(tableName+"维度表存在redis的数据>>>>"+dimJsonStr+">>>>>key>>>"+redisKey.toString());
            dimJsonObj = JSON.parseObject(dimJsonStr);
        }else {
            System.out.println("hbase查询维度表的sql为：" + querySql);
            List<JSONObject> dimJsonObjectList = PhoenixUtil.queryList(querySql.toString(), JSONObject.class);
            System.out.println(tableName+"维度表存在hbase的数据>>>>"+dimJsonObjectList);
            //查到数据,保存到redis一份保存一天,并返回
            if (dimJsonObjectList!=null && dimJsonObjectList.size()>0){
                dimJsonObj=dimJsonObjectList.get(0);
                //上边redis在try catch 中可能出现错误导致没有获取到jedis,所以要加判断
                if (jedis!=null){
                    jedis.setex(redisKey.toString(),3600*24,dimJsonObj.toJSONString());
                }
            }else {
                System.out.println("没有查询到维度数据:" + querySql);
            }
        }

        //关闭jedis连接
        if (jedis!=null){
            jedis.close();
            System.out.println("关闭redis缓存连接 ");
        }

        return dimJsonObj;
    }

    /**
     * 根据id查询维度表数据
     * @param tableName
     * @param id
     * @return
     */
    public static JSONObject getDimInfo(String tableName, String id) {
        return getDimInfo(tableName,Tuple2.of("id",id));
    }

    /**
     * 删除redis缓存
     * @param tableName
     * @param id
     */
    public static void deleteCached(String tableName,String id){
        String redisKey = "dim:"+tableName.toLowerCase()+":" + id;
        try {
            Jedis jedis = RedisUtil.getJedis();
            jedis.del(redisKey);
            jedis.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("删除redis缓存异常,维度表:"+tableName);
        }
    }

    public static void main(String[] args) {
//        JSONObject dimJsonObj = getDimInfoNoCache("DIM_BASE_TRADEMARK", Tuple2.of("id", "14"),Tuple2.of("tm_name","cc"));
//        JSONObject dimJsonObj = getDimInfo("DIM_BASE_TRADEMARK", Tuple2.of("id", "14"));
//        JSONObject dimJsonObj = getDimInfo("DIM_BASE_TRADEMARK", "14");
//        System.out.println(dimJsonObj);
    }

}
